package com.mobile.service.impl;

import cn.hutool.core.date.DateUtil;
import com.mobile.domain.dto.ChatDTO;
import com.mobile.embedding.RuleEmbedding;
import com.mobile.service.MobileChatService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

@Slf4j
@RequiredArgsConstructor
@Service
public class MobileChatServiceImpl implements MobileChatService {

    private final ChatClient client;
    private final VectorStore vectorStore;
    private final RuleEmbedding ruleEmbedding;

    /**
     * 移动端流式聊天
     * @param chatDTO 聊天参数
     * @return 聊天结果
     */
    @Override
    public Flux<String> streamChat(ChatDTO chatDTO) {
        // 检查初始化状态
        if (!ruleEmbedding.isInitialized()) {
            if (ruleEmbedding.isInitializing()) {
                return Flux.just("系统正在初始化中，请稍后重试...", "[END]");
            } else {
                return Flux.just("系统初始化失败，暂时无法提供服务", "[END]");
            }
        }

        var searchRequest = SearchRequest.builder()
                .query(chatDTO.getQuestion())//搜索条件
                .topK(3)//最多返回的文档数量
                .build();

        return client.prompt()
                .system(prompt -> prompt.param("now", DateUtil.now()))
                .user(chatDTO.getQuestion())
                //设置会话记忆参数
                .advisors(advisor -> advisor.advisors(
                                new QuestionAnswerAdvisor(vectorStore, searchRequest))
                        .param(AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY, chatDTO.getSessionId()))
                .stream()
                .content()
                .doOnNext(s-> log.info("{}", s))
                .concatWith(Flux.just("[END]"));
    }
}
